﻿using System;
using System.Collections.Generic;
using Gasco.DataAccess;
using System.Linq;
using System.Data.Linq;

namespace Gasco.Business.Services
{
    public class ProductService : IProductService
    {

        #region IProductService Members

        public IList<origin> GetOrigins()
        {
          var db = DatabaseHelper.GetData();
          var result=from o in db.origins
                     select o;
            return result.ToList<origin>();
        }

        public int CountOrigins(origin example)
        {
            var db = DatabaseHelper.GetData();
            return db.origins.Count();
        }

      
        public IList<product> GetProducts()
        {
            var db = DatabaseHelper.GetData();
            return db.products.ToList<product>();
        }

        public product CreateProduct(product p)
        {
            product result = CheckForDuplicateProduct(p.product_type_id, p.name);
            if (result != null && result.id != p.id)
                throw new DuplicateProduct();
            
            return DatabaseHelper.Insert<product>(p);
        }

        public origin CreateOrigin(origin o)
        {
           return   DatabaseHelper.Insert<origin>(o);
        }

        public void UpdateOrigin(origin o)
        {
             DatabaseHelper.Update<origin>(o);
        }

        public IList<product_type> GetProductType(product_type example)
        {
            var db = DatabaseHelper.GetData();
            var result = from pt in db.product_types
                          select pt;
            return result.ToList<product_type>(); 
        }


        public int CountProducts()
        {
            var db = DatabaseHelper.GetData();
            return db.products.Count();
        }

        public product GetProductById(int id)
        {
            product product = null;
            using (var db = DatabaseHelper.GetData())
            {
                db.DeferredLoadingEnabled = false;

                product = (from p in db.products
                          where (p.id == id)
                          select p).First();
            }
            product.SetAsChangeTrackingRoot(true);
            return product;

        }

        public origin GetOriginById(int id)
        {
            origin origin = null;
            using (var db = DatabaseHelper.GetData())
            {
                db.DeferredLoadingEnabled = false;

                origin = (from o in db.origins
                          where (o.id == id)
                          select o).FirstOrDefault();
            }

            if ( origin != null )
                origin.SetAsChangeTrackingRoot(true);

            return origin;
        }


        public void UpdateProduct(product p)
        {
            product result = CheckForDuplicateProduct(p.product_type_id, p.name);
            if (result != null && result.id != p.id)
                throw new DuplicateProduct();

            DatabaseHelper.Update<product>(p);
        }

        public void DeleteProduct(int id)
        {
            product p = GetProductById(id);
            DatabaseHelper.Delete<product>(p);
        }

        public void DeleteOrigin(int id)
        {
            origin o = GetOriginById(id);
            DatabaseHelper.Delete<origin>(o);
        }

        public IList<unit> GetUnit(unit example) 
        {
            var db = DatabaseHelper.GetData();
            var result = from u in db.units
                         select u;

            return result.ToList<unit>();
        }

        public List<product> SearchProducts(string keyword, int pageSize, int pageNumber, string sortBy, string sortDirection)
        {
            var db = DatabaseHelper.GetData();
            IQueryable<product> result = null;

           if (String.IsNullOrEmpty(keyword))
            {
                result = from p in db.products
                         select p;
            }
            else
            {
                result = from p in db.products
                         where (p.name.Contains(keyword) || p.product_type1.name.Contains(keyword) || p.name.Contains(keyword))
                         select p;
            }
           if (sortDirection.ToLower() == "descending")
               sortBy = String.Format("{0} DESC", sortBy);
             
           return result.Skip((pageNumber - 1) * pageSize).Take(pageSize).SortBy<product>(sortBy).ToList<product>();

        }


        public int CountSearchProducts(string keyword)
        {
            var db = DatabaseHelper.GetData();
            IQueryable<product> result = null;
            if (String.IsNullOrEmpty(keyword))
            {
                result = from p in db.products
                         select p;
            }
            else
            {
                result = from p in db.products
                         where (p.name.Contains(keyword) || p.product_type1.name.Contains(keyword))
                         select p;
            }

            return result.Count();

        }
        
        
        public List<origin> SearchOrigins(string keyword, int pageSize, int pageNumber, string sortBy, string sortDirection)
        {
            var db = DatabaseHelper.GetData();
            IQueryable<origin> result = null;

            if (String.IsNullOrEmpty(keyword))
            {

                result = from o in db.origins
                         select o;
            }
            else
            {
                result = from o in db.origins
                         where (o.refinery.Contains(keyword)|| o.city.name.Contains(keyword)||
                               o.city.country.name.Contains(keyword)) 
                         select o;
            }

            if (sortDirection.ToLower() == "descending")
                sortBy = String.Format("{0} DESC", sortBy);

            return result.Skip((pageNumber - 1) * pageSize).Take(pageSize).SortBy<origin>(sortBy).ToList<origin>();
        }


        public int CountSearchOrigins(string keyword)
        {
            var db = DatabaseHelper.GetData();
            IQueryable<origin> result = null;

            if (String.IsNullOrEmpty(keyword))
            {

                result = from o in db.origins
                         select o;
            }
            else
            {
                result = from o in db.origins
                         where (o.refinery.Contains(keyword) || o.city.name.Contains(keyword) ||
                                o.city.country.name.Contains(keyword))
                         select o;
            }

            return result.Count();
        }


        public product CheckForDuplicateProduct(int product_type, string product_name)
        {
            GascoDBDataContext db = DatabaseHelper.GetData();

            var result = from p in db.products
                         where (p.product_type_id == product_type && p.name == product_name)
                         select p;
            return result.FirstOrDefault<product>();
        }
        #endregion
    }
}
